import { checkToken, useAccessToken } from "@/authorization/useAuthorization"
import { useAppStore } from "@/store/modules/app"
import { useAuthStore } from "@/store/modules/auth"
import { isEmpty, loadingBar, log } from "@/utils"
import { RouteLocationNormalized, Router } from "vue-router"
import Layout from "@/layout/Index.vue"
import { useRouteStore } from "@/store/modules/route"
import { useThemeStore } from "@/store/modules/theme"

const NotFoundPageRoute = {
    path: "/:path(.*)*",
    name: "ErrorPage",
    component: Layout,
    meta: {
        title: "未找到页面"
    },
    children: [
        {
            path: "/:path(.*)*",
            name: "404",
            component: () => import("@/views/base/error/404.vue"),
            meta: {
                title: "未找到页面",
                needLogin: true
            }
        }
    ]
}

export function createRouterGuards(router: Router) {
    router.beforeEach(async to => {
        log.info("开始导航 => " + to.fullPath)
        // 开启进度条
        loadingBar.start()
        // 重定向
        if (to.name === "Redirect") {
            return
        }
        // 不需要登录校验的，直接转向
        const needLogin = determineNeedLogin(to)
        if (!needLogin) {
            return
        }
        const token = useAccessToken()
        const authStore = useAuthStore()
        // 登录校验
        if (isEmpty(token.value)) {
            authStore.logout()
            return { path: "login" }
        }
        if (authStore.isLogin) {
            return
        }
        await checkToken()
        // 添加404
        const isErrorPage = router.getRoutes().findIndex(item => item.name === "404")
        if (isErrorPage === -1) {
            router.addRoute(NotFoundPageRoute)
        }
        return { path: to.path, replace: true }
    })

    router.afterEach(to => {
        setWindowsTitle(to)
        addToKeepAliveQueue(to)
        loadingBar.finish()
    })

    router.onError(error => {
        console.log(error, "路由错误")
    })
}

/**
 * 根据 router.meta.needLogin 判断是否需要登录校验
 */
function determineNeedLogin(router: RouteLocationNormalized): boolean {
    let needLogin
    const matched = router.matched
    if (isEmpty(matched)) {
        return true
    }
    const length = matched.length
    for (let i = length; i > 0; i--) {
        const current = matched[i - 1]
        if (current.meta && Reflect.has(current.meta, "needLogin")) {
            needLogin = current.meta.needLogin
            break
        }
    }
    // 默认不需要登录
    return needLogin === true
}

/**
 * 设置 router.meta.title 为标题
 */
const setWindowsTitle = (router: RouteLocationNormalized) => {
    const title = useTitle()
    const appStore = useAppStore()
    const { setting } = storeToRefs(appStore)
    let subTitle = router.meta.title
    let rootTitle = setting.value?.title ?? ""
    if (isEmpty(subTitle)) {
        title.value = rootTitle
    } else {
        title.value = subTitle + " - " + rootTitle
    }
}

/**
 * 添加到 keepAlive 队列
 */
const addToKeepAliveQueue = (router: RouteLocationNormalized) => {
    const routeStore = useRouteStore()
    const themeStore = useThemeStore()
    const { setting } = storeToRefs(themeStore)
    if (setting.value?.useMultiTabs) {
        if (router.name !== "Redirect") {
            routeStore.addCacheView(router)
        }
    } else {
        routeStore.clear()
    }
}
